package pers.bc.utils.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import com.alibaba.fastjson.JSONObject;

/**
 * rest  风格请求处理
 **
 * @qualiFild pers.bc.utils.net.RequestParserUtil.java<br>
 * @author：LiBencheng<br>
 * @date Created on 2025年3月17日<br>
 * @version 1.0<br>
 */
public class RequestParserUtil
{
    
    /**
     * *********************************************************** <br>
     * *说明： 获取请求头信息<br>
     * @see <br>
     * @param request
     * @return <br>
     * @Map<String,String> <br>
     * @methods pers.bc.utils.net.RequestParser#getHeaders <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:17:05 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static Map<String, String> getHeaders(HttpServletRequest request)
    {
        Map<String, String> headers = new HashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        
        while (headerNames.hasMoreElements())
        {
            String name = headerNames.nextElement();
            headers.put(name, request.getHeader(name));
        }
        
        return headers;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 获取原始请求体内容<br>
     * @see <br>
     * @param request
     * @return
     * @throws IOException <br>
     * @String <br>
     * @methods pers.bc.utils.net.RequestParser#getRequestBody <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:16:50 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static String getRequestBody(HttpServletRequest request) throws IOException
    {
        return request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
    }
    
    /**
     * *********************************************************** <br>
     * *说明：解析查询参数（URL参数） <br>
     * @see <br>
     * @param request
     * @return <br>
     * @Map<String,List<String>> <br>
     * @methods pers.bc.utils.net.RequestParser#parseQueryParameters <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:15:44 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static Map<String, List<String>> parseQueryParameters(HttpServletRequest request)
    {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, List<String>> result = new HashMap<>();
        
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet())
        {
            result.put(entry.getKey(), Arrays.asList(entry.getValue()));
        }
        return result;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 解析表单数据（application/x-www-form-urlencoded）<br>
     * @see <br>
     * @param request
     * @return
     * @throws IOException <br>
     * @Map<String,List<String>> <br>
     * @methods pers.bc.utils.net.RequestParser#parseFormData <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:16:07 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static Map<String, List<String>> parseFormData(HttpServletRequest request) throws IOException
    {
        // 如果已经调用过getParameter相关方法，可以直接使用getParameterMap
        return parseQueryParameters(request);
    }
    
    /**
     * *********************************************************** <br>
     * *说明：解析JSON请求体（application/json） <br>
     * @see <br>
     * @param request
     * @return
     * @throws IOException <br>
     * @Map<String,Object> <br>
     * @methods pers.bc.utils.net.RequestParser#parseJsonBody <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:16:30 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static Map<String, Object> parseJsonBody(HttpServletRequest request) throws IOException
    {
        String body = getRequestBody(request);
        
        return JSONObject.parseObject(body);
        // 这里使用Jackson库示例，需要添加相关依赖
        // ObjectMapper mapper = new ObjectMapper();
        // return mapper.readValue(body, Map.class);
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 解析multipart/form-data（文件上传）<br>
     * @see <br>
     * @param request
     * @return
     * @throws IOException
     * @throws ServletException <br>
     * @Map<String,Object> <br>
     * @methods pers.bc.utils.net.RequestParser#parseMultipartFormData <br>
     * @author LiBencheng <br>
     * @date Created on 2025年3月1日 <br>
     * @time 13:16:41 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static Map<String, Object> parseMultipartFormData(HttpServletRequest request) throws IOException, ServletException
    {
        Map<String, Object> result = new HashMap<>();
        if (request.getContentType() != null && request.getContentType().startsWith("multipart/form-data"))
        {
            Collection<Part> parts = request.getParts();
            for (Part part : parts)
            {
                String name = part.getName();
                String fileName = part.getSubmittedFileName();
                if (fileName == null)
                {
                    // 普通表单字段
                    String value =
                        new BufferedReader(new InputStreamReader(part.getInputStream())).lines().collect(Collectors.joining("\n"));
                    result.put(name, value);
                }
                else
                {
                    // 文件处理
                    InputStream fileContent = part.getInputStream();
                    // 这里可以将文件保存到服务器或进行其他处理
                    Map<String, Object> fileInfo = new HashMap<>();
                    fileInfo.put("fileName", fileName);
                    fileInfo.put("size", part.getSize());
                    fileInfo.put("contentType", part.getContentType());
                    result.put(name, fileInfo);
                }
            }
        }
        
        return result;
    }
    
    // 示例使用方法
    public static void processRequest(HttpServletRequest request)
    {
        try
        {
            // 获取请求头
            Map<String, String> headers = getHeaders(request);
            
            // 根据Content-Type处理不同格式
            String contentType = request.getContentType();
            
            if (contentType == null)
            {
                // 处理GET请求参数
                Map<String, List<String>> queryParams = parseQueryParameters(request);
                System.out.println("Query Parameters: " + queryParams);
            }
            else if (contentType.startsWith("application/x-www-form-urlencoded"))
            {
                Map<String, List<String>> formData = parseFormData(request);
                System.out.println("Form Data: " + formData);
            }
            else if (contentType.startsWith("application/json"))
            {
                Map<String, Object> jsonBody = parseJsonBody(request);
                System.out.println("JSON Body: " + jsonBody);
            }
            else if (contentType.startsWith("multipart/form-data"))
            {
                Map<String, Object> formData = parseMultipartFormData(request);
                System.out.println("Multipart Data: " + formData);
            }
            
            // 获取客户端信息
            String clientIP = request.getRemoteAddr();
            String method = request.getMethod();
            System.out.println("Client IP: " + clientIP + ", Method: " + method);
            
        }
        catch (Exception e)
        {
          
        }
    }
}
